Start accepting [lib], allow `bin = []`
authorAlex Crichton <alex@alexcrichton.com>
Thu, 14 Aug 2014 06:02:08 +0000 (23:02 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 14 Aug 2014 06:02:08 +0000 (23:02 -0700)
This commit starts to accept `[lib]` as a single library per package. It also
allows opting-out of binaries/tests/examples with a top level `foo = []` rather
than taking an empty array to mean that inference should be enabled.

cc #327

src/cargo/util/toml.rs
tests/test_cargo_compile.rs

index 20aba7688c047fd0f58cb32e17b24742306a5018..20d62aae0794976a3d019e5c28532f7b1c5f5a9a 100644 (file)
@@ -2,6 +2,7 @@ use serialize::Decodable;
 use std::collections::HashMap;
 use std::fmt;
 use std::io::fs;
+use std::slice;
 use std::str;
 use toml;
 
@@ -183,7 +184,7 @@ pub struct DetailedTomlDependency {
 pub struct TomlManifest {
     package: Option<Box<TomlProject>>,
     project: Option<Box<TomlProject>>,
-    lib: Option<Vec<TomlLibTarget>>,
+    lib: Option<ManyOrOne<TomlLibTarget>>,
     bin: Option<Vec<TomlBinTarget>>,
     example: Option<Vec<TomlExampleTarget>>,
     test: Option<Vec<TomlTestTarget>>,
@@ -191,6 +192,21 @@ pub struct TomlManifest {
     dev_dependencies: Option<HashMap<String, TomlDependency>>
 }
 
+#[deriving(Encodable,Decodable,PartialEq,Clone)]
+pub enum ManyOrOne<T> {
+    Many(Vec<T>),
+    One(T),
+}
+
+impl<T> ManyOrOne<T> {
+    fn as_slice(&self) -> &[T] {
+        match *self {
+            Many(ref v) => v.as_slice(),
+            One(ref t) => slice::ref_slice(t),
+        }
+    }
+}
+
 #[deriving(Decodable,Encodable,PartialEq,Clone,Show)]
 pub struct TomlProject {
     pub name: String,
@@ -296,48 +312,48 @@ impl TomlManifest {
         // If we have a lib with a path, we're done
         // If we have a lib with no path, use the inferred lib or_else package name
 
-        let lib = if self.lib.is_none() || self.lib.get_ref().is_empty() {
-            inferred_lib_target(project.name.as_slice(), layout)
-        } else {
-            self.lib.get_ref().iter().map(|t| {
-                if layout.lib.is_some() && t.path.is_none() {
-                    TomlTarget {
-                        path: layout.lib.as_ref().map(|p| TomlPath(p.clone())),
-                        .. t.clone()
+        let lib = match self.lib {
+            Some(ref libs) => {
+                libs.as_slice().iter().map(|t| {
+                    if layout.lib.is_some() && t.path.is_none() {
+                        TomlTarget {
+                            path: layout.lib.as_ref().map(|p| TomlPath(p.clone())),
+                            .. t.clone()
+                        }
+                    } else {
+                        t.clone()
                     }
-                } else {
-                    t.clone()
-                }
-            }).collect()
+                }).collect()
+            }
+            None => inferred_lib_target(project.name.as_slice(), layout),
         };
 
-        let bins = if self.bin.is_none() || self.bin.get_ref().is_empty() {
-            inferred_bin_targets(project.name.as_slice(), layout)
-        } else {
-            let bin = layout.main();
+        let bins = match self.bin {
+            Some(ref bins) => {
+                let bin = layout.main();
 
-            self.bin.get_ref().iter().map(|t| {
-                if bin.is_some() && t.path.is_none() {
-                    TomlTarget {
-                        path: bin.as_ref().map(|&p| TomlPath(p.clone())),
-                        .. t.clone()
+                bins.iter().map(|t| {
+                    if bin.is_some() && t.path.is_none() {
+                        TomlTarget {
+                            path: bin.as_ref().map(|&p| TomlPath(p.clone())),
+                            .. t.clone()
+                        }
+                    } else {
+                        t.clone()
                     }
-                } else {
-                    t.clone()
-                }
-            }).collect()
+                }).collect()
+            }
+            None => inferred_bin_targets(project.name.as_slice(), layout)
         };
 
-        let examples = if self.example.is_none() || self.example.get_ref().is_empty() {
-            inferred_example_targets(layout)
-        } else {
-            self.example.get_ref().iter().map(|t| t.clone()).collect()
+        let examples = match self.example {
+            Some(ref examples) => examples.clone(),
+            None => inferred_example_targets(layout),
         };
 
-        let tests = if self.test.is_none() || self.test.get_ref().is_empty() {
-            inferred_test_targets(layout)
-        } else {
-            self.test.get_ref().iter().map(|t| t.clone()).collect()
+        let tests = match self.test {
+            Some(ref tests) => tests.clone(),
+            None => inferred_test_targets(layout),
         };
 
         // Get targets
index d5d3f0555b9e6a1921e176795fcbb247f15bdd46..76c9ba901fae72b8c49332ece0922e3351966cf5 100644 (file)
@@ -1422,3 +1422,49 @@ test!(simple_staticlib {
 
     assert_that(p.cargo_process("cargo-build"), execs().with_status(0));
 })
+
+test!(opt_out_of_lib {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+              lib = []
+
+              [package]
+              name = "foo"
+              authors = []
+              version = "0.0.1"
+        "#)
+        .file("src/lib.rs", "bad syntax")
+        .file("src/main.rs", "fn main() {}");
+    assert_that(p.cargo_process("cargo-build"), execs().with_status(0));
+})
+
+test!(opt_out_of_bin {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+              bin = []
+
+              [package]
+              name = "foo"
+              authors = []
+              version = "0.0.1"
+        "#)
+        .file("src/lib.rs", "")
+        .file("src/main.rs", "bad syntax");
+    assert_that(p.cargo_process("cargo-build"), execs().with_status(0));
+})
+
+test!(single_lib {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+              [package]
+              name = "foo"
+              authors = []
+              version = "0.0.1"
+
+              [lib]
+              name = "foo"
+              path = "src/bar.rs"
+        "#)
+        .file("src/bar.rs", "");
+    assert_that(p.cargo_process("cargo-build"), execs().with_status(0));
+})